package com.geeguo.ebuilder.operation.config;

import com.geeguo.ebuilder.core.common.action.ActionResult;
import com.geeguo.ebuilder.core.common.action.ActionResultCode;
import com.geeguo.ebuilder.core.common.exception.ApplicationException;
import com.geeguo.ebuilder.core.common.exception.FrameworkException;
import com.geeguo.ebuilder.core.common.utils.GsonUtils;
import com.geeguo.ebuilder.core.security.exception.NotLoginException;
import com.geeguo.ebuilder.core.security.exception.NotPermissionException;
import com.geeguo.ebuilder.core.security.exception.NotRoleException;
import com.geeguo.ebuilder.core.security.exception.SessionOverdueException;
import com.geeguo.ebuilder.operation.base.core.constants.MessageConstants;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 登录过期
     */
    @ExceptionHandler(SessionOverdueException.class)
    public ActionResult<String> handleSessionOverdueException(SessionOverdueException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}', 登录过期'{}'", requestURI, e.getMessage());
        return ActionResult.fail(ActionResultCode.SessionOverdue);
    }
    
	/**
     * 登录校验异常
     */
    @ExceptionHandler(NotLoginException.class)
    public ActionResult<String> handleNotLoginException(NotLoginException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}', 登录校验失败'{}'", requestURI, e.getMessage());
        return ActionResult.fail(ActionResultCode.Unauthorized);
    }
	
	/**
     * 角色校验异常
     */
    @ExceptionHandler(NotRoleException.class)
    public ActionResult<String> handleNotRoleException(NotRoleException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}', 角色校验失败'{}'", requestURI, e.getMessage());
        return ActionResult.fail(ActionResultCode.Unauthorized);
    }
    
	/**
     * 权限校验异常
     */
    @ExceptionHandler(NotPermissionException.class)
    public ActionResult<String> handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}', 权限校验失败'{}'", requestURI, e.getMessage());
        return ActionResult.fail(ActionResultCode.Unauthorized);
    }

    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ActionResult<String> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}', 不支持'{}'请求", requestURI, e.getMethod());
        return ActionResult.fail(e.getMessage());
    }

    /**
     * 参数异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ActionResult<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        Map<String, String> map = new HashMap<>();
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        for (FieldError item : fieldErrors) {
            map.put(item.getField(), item.getDefaultMessage());
        }
        String json = GsonUtils.toJson(map);
        return ActionResult.fail(ActionResultCode.Fail, MessageConstants.FAIL_REQUEST_DATA_ERROR, json);
    }

    /**
     * 参数异常
     */
    @ExceptionHandler(BindException.class)
    public ActionResult<String> handleBindException(BindException e) {
        Map<String, String> map = new HashMap<>();
        List<FieldError> fieldErrors = e.getFieldErrors();
        for (FieldError item : fieldErrors) {
            map.put(item.getField(), item.getDefaultMessage());
        }
        String json = GsonUtils.toJson(map);
        return ActionResult.fail(ActionResultCode.Fail, MessageConstants.FAIL_REQUEST_DATA_ERROR, json);
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(ApplicationException.class)
    public ActionResult<String> handleApplicationException(ApplicationException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}', 发生业务异常:{}", requestURI, e.getMessage(), e);
        return ActionResult.fail(e.getMessage());
    }

    /**
     * 基础异常
     */
    @ExceptionHandler(FrameworkException.class)
    public ActionResult<String> handleFrameworkException(FrameworkException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}', 发生基础异常:{}", requestURI, e.getMessage(), e);
        return ActionResult.fail(MessageConstants.UNKNOWN_ERROR);
    }

    /**
     * 其它异常
     */
    @ExceptionHandler(Exception.class)
    public ActionResult<String> handleException(Exception e, HttpServletRequest request) {
    	String requestURI = request.getRequestURI();
        log.error("请求地址'{}', 发生系统异常.", requestURI, e);
        return ActionResult.fail(MessageConstants.UNKNOWN_ERROR);
    }
}